#!/usr/bin/env python
#
#       properties.py
#
#       Copyright 2009 Chris Glass <tribaal@gmail.com>
#
#       This program is free software: you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation, either version 3 of the License, or
#       (at your option) any later version.
#
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#
#       You should have received a copy of the GNU General Public License
#       along with this program.  If not, see <http://www.gnu.org/licenses/>.


from cgi import escape

class props :
    
    time_words = {}
    
    def __init__(self):
        self.time_words = {}

    def _parse_properties(self, iterable):
        dictionnary = {}
        peers = list()
        for line in iterable : #For each line in the file...

            # If the line doesn't start by a comment, is empty or only a
            # newline char is present...
            if line[0] != '#' and line != '\n' and line != '' :

                first_word = line.split(' ')[0]
                if first_word != 'cache' and first_word != 'don\'t' \
                                         and first_word != 'time':
                    #Split the line on the '=' sign
                    line_map = line.split('=')
                    if len(line_map) != 2:
                        continue
                    #Always escape user input to prevent code injection!
                    my_property = escape(line_map[0])
                    my_property = my_property.strip()
                    #value = escape(map[1][:-1])
                    value = escape(line_map[1])

                    if value[-1:] == '\n' : # We don't want the trailing '\n'
                        value = value[:-1]

                    if my_property == "peers" :
                        peers.append(value.strip())
                        dictionnary[my_property] = peers
                    else :
                        dictionnary[my_property] = value.strip()
                        
        # This retrieves the rules from the supplied file and appends
        # them to the properties dictionnary.
        cache, nocache = self._parse_rules(iterable)
        
        # If we have none, no need to append them :)
        
        dictionnary['cache_rules'] = cache
        dictionnary['no_cache_rules'] = nocache
            
        return dictionnary

    def _parse_rules(self, iterable):
        cache = {}
        dontcache = []
        
        for line in iterable:
            # If line is not a comment nor empty...
            if line[0] != '#' and line != '\n' and line != '' :
                words = line.split(" ")
                if words[0] == "cache":
                    regexp = words[1]
                    # there should be a "for" in words[2]
                    assert words[2] == "for"
                    time = words[3]
                    cache[regexp] = self._parse_time(time)
                    #print "Regexp:", regexp, "should be cached"
                     
                elif words[0] == "time":
                    name = words[1]
                    lenght = self._parse_time(words[2])
                    self.time_words[name] = lenght
                
                elif words[0] == "don't" and words[1] == "cache":
                    dontcache.append(words[2])
                    #print "Regexp:", words[2], "shouldn't be cached!"

        return cache , dontcache

    def _parse_time(self, time):
        '''The purpose of this method is to translate whatever time the
        user supplied to seconds, including user-supplied time 
        definitions'''
        # Let's make sure we have no junk here.
        if time[-1:] == '\n':
            time = time[:-1]
        
        if time in self.time_words: # Always looks through the keys
            time = self.time_words[time]
        else:
            if time[-1:] == 'd' :
                time = long(time[:-1]) * 24 * 60 * 60
            elif time[-1:] == 'h':
                time = long(time[:-1]) * 60 * 60
            elif time[-1:] == 'm':
                time = long(time[:-1]) * 60
            elif time[-1:] == 's':
                time = long(time[:-1])
            else:
                # Assume seconds
                time = long(time)
        return time
        

    def load_rules(self, filename="cache.conf"):
        with open(filename, "r") as propfile:
            file_content = propfile.readlines()
        return self._parse_rules(file_content)


    # Returns a dict containing properties:
    # Special fields include:
    # props['peers'] = <a list of peers>
    # props['cache_rules'] = <a dict of cache rules, as {<regexp>:<time>}>
    def load_properties(self, file_name='cache.conf'):
        ''' Loads properties from the specified 'file_name' configuration file'''
        with open(file_name, "r") as propfile:
            file_content = propfile.readlines()
        return self._parse_properties(file_content)


